package org.csu.onlineedubackend.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.RandomStringUtils;
import org.csu.onlineedubackend.dto.OAuthUserInfoDTO;
import org.csu.onlineedubackend.entity.User;
import org.csu.onlineedubackend.mapper.UserMapper;
import org.csu.onlineedubackend.service.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import cn.dev33.satoken.stp.StpUtil;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * OAuth第三方登录服务实现类
 */
@Service
public class OAuthServiceImpl implements OAuthService {

    @Value("${oauth.gitee.client_id}")
    private String clientId;

    @Value("${oauth.gitee.client_secret}")
    private String clientSecret;

    @Value("${oauth.gitee.redirect_uri}")
    private String redirectUri;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 获取Gitee的access_token
     * @param code 授权码
     * @return access_token
     */
    @Override
    public String getGiteeAccessToken(String code) {
        try {
            // 准备请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("grant_type", "authorization_code");
            params.add("code", code);
            params.add("client_id", clientId);
            params.add("client_secret", clientSecret);
            params.add("redirect_uri", redirectUri);

            // 发送POST请求获取access_token
            String tokenUrl = "https://gitee.com/oauth/token";
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept", "application/json");
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                    tokenUrl,
                    HttpMethod.POST,
                    requestEntity,
                    String.class
            );
            
            // 解析响应获取access_token
            JsonNode root = objectMapper.readTree(response.getBody());
            return root.path("access_token").asText();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取Gitee用户信息
     * @param accessToken 授权令牌
     * @return 用户信息
     */
    @Override
    public OAuthUserInfoDTO getGiteeUserInfo(String accessToken) {
        try {
            // 准备请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "token " + accessToken);

            // 发送GET请求获取用户信息
            String userInfoUrl = "https://gitee.com/api/v5/user";
            HttpEntity<?> requestEntity = new HttpEntity<>(headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                    userInfoUrl,
                    HttpMethod.GET,
                    requestEntity,
                    String.class
            );
            
            // 解析响应获取用户信息
            JsonNode root = objectMapper.readTree(response.getBody());
            
            return OAuthUserInfoDTO.builder()
                    .id(root.path("id").asText())
                    .login(root.path("login").asText())
                    .name(root.path("name").asText())
                    .avatarUrl(root.path("avatar_url").asText())
                    .platform("gitee")
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 处理Gitee用户登录或注册
     * @param userInfo Gitee用户信息
     * @return 登录结果
     */
    @Override
    public Map<String, Object> loginOrRegisterGiteeUser(OAuthUserInfoDTO userInfo) {
        // 使用Gitee用户名直接查找数据库中的用户
        User user = userMapper.selectByUsername(userInfo.getLogin());
        
        if (user == null) {
            // 如果找不到对应用户，返回错误信息
            Map<String, Object> result = new HashMap<>();
            result.put("error", "用户不存在");
            result.put("loginName", userInfo.getLogin());
            return result;
        }
        
        // 找到用户，执行登录 - 模拟普通登录流程
        StpUtil.login(user.getId());
        
        // 准备返回数据，与普通登录完全保持一致的格式
        Map<String, Object> result = new HashMap<>();
        
        // 设置登录令牌信息 - 这是与普通登录保持一致的关键
        result.put("saTokenInfo", StpUtil.getTokenInfo());
        
        // 用户信息在普通登录中是直接放在返回结果中的，而不是嵌套在userInfo对象里
        result.put("userId", user.getId());
        result.put("username", user.getUsername());
        result.put("role", user.getRole());
        result.put("name", user.getName());
        
        // token值实际上是从saTokenInfo中获取的，但为了保持一致也直接添加
        result.put("token", StpUtil.getTokenValue());
        
        return result;
    }
} 